﻿#include "MultipleVideosPlayController.h"

extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
}
void MultipleVideosPlayController::Start()
{
	// 创建并启动后台线程
	renderThread = std::make_unique<std::thread>(&MultipleVideosPlayController::Draw, this);
}

QString MultipleVideosPlayController::Init()
{
	binaryFileReader = BinaryFileReader::Create();
	iVideoRenderView = IVideoRenderView::Create(IVideoRenderView::SDL);
	if (mWidth <= 0 || mHeight <= 0 || win_id == NULL)
	{
		qDebug() << "请设要播放文件的宽高";
		QString errorMsg = "请设要播放文件的宽高";
		return errorMsg;
	}

	binaryFileReader->filename = mFilePath.toStdString();
	binaryFileReader->width = mWidth;
	binaryFileReader->height = mHeight;
	binaryFileReader->Init();

	IVideoRenderView::PixFormat mFormat = IVideoRenderView::PixFormat::RGBA;
	switch (mPixFormat) {
	case 0:
		mFormat = IVideoRenderView::PixFormat::RGBA;
		data = new  char[mWidth * mHeight * 4];
		linesize = mWidth * mHeight * 4;
		break;
	case 1:
		mFormat = IVideoRenderView::PixFormat::ARGB;
		data = new  char[mWidth * mHeight * 4];
		linesize = mWidth * mHeight * 4;
		break;
	case 2:
		mFormat = IVideoRenderView::PixFormat::RGB24;
		data = new  char[mWidth * mHeight * 3];
		linesize = mWidth * mHeight * 3;
		break;
	case 3:
		mFormat = IVideoRenderView::PixFormat::YUV420P;
		data = new  char[mWidth * mHeight * 1.5];
		linesize = mWidth * mHeight * 1.5;
		break;
	}
	iVideoRenderView->Init(mWidth, mHeight, mFormat, win_id);
	return NULL;
}

/// <summary>
/// 线程函数，执行了线程
/// </summary>
void MultipleVideosPlayController::Draw()
{
	for (;;)
	{
		if (!isRunning)break;
		bool ret = binaryFileReader->Read(data, linesize);
		AVFrame* frame = GetFrame(data);
		if (!ret) {
			break;
		}
		iVideoRenderView->DrawFrame(frame);
		av_frame_free(&frame);//释放掉AVFrame
		if (fps <= 0)
		{
			fps = 25;
		}
		int secondMs = (int)(1000 / fps);
		//std::this_thread::sleep_for(33ms);
		std::this_thread::sleep_for(std::chrono::milliseconds(secondMs));
		int renderFps = iVideoRenderView->RenderFps();
		callback(renderFps);
	}
	qDebug() << "已释放了data内存";
}
AVFrame* MultipleVideosPlayController::GetFrame(char* data)
{
	AVFrame* frame = av_frame_alloc();
	frame->width = mWidth;
	frame->height = mHeight;
	switch (mPixFormat) {
	case IVideoRenderView::PixFormat::YUV420P:
		frame->format = AV_PIX_FMT_YUV420P;//设置像素格式
		//设置linesize
		frame->linesize[0] = mWidth;
		frame->linesize[1] = mWidth / 2;
		frame->linesize[2] = mWidth / 2;
		break;
	case IVideoRenderView::PixFormat::RGB24:
		frame->format = AV_PIX_FMT_RGB24;//设置像素格式
		//设置linesize
		frame->linesize[0] = mWidth * 3;
		break;
	case IVideoRenderView::PixFormat::RGBA:
		frame->format = AV_PIX_FMT_RGBA;//设置像素格式
		//设置linesize
		frame->linesize[0] = mWidth*3;
	case IVideoRenderView::PixFormat::ARGB:
		frame->format = AV_PIX_FMT_ARGB;//设置像素格式
		//设置linesize
		frame->linesize[0] = mWidth*4;
		break;

	}
	//生成图像空间,默认32字节对齐
	int ret = av_frame_get_buffer(frame, 0);

	switch (mPixFormat) {
	case IVideoRenderView::PixFormat::YUV420P:
	{
		//outputErrorMsg(ret, "AVFrame生成图像空间");
		size_t y_size = mWidth * mHeight;
		size_t uv_size = (mWidth / 2) * (mHeight / 2);
		uint8_t* y_data = (uint8_t*)data;
		uint8_t* u_data = y_data + y_size;
		uint8_t* v_data = u_data + uv_size;
		frame->data[0] = y_data;
		frame->data[1] = u_data;
		frame->data[2] = v_data;
	}
		
		break;
	case IVideoRenderView::PixFormat::RGB24:
	case IVideoRenderView::PixFormat::RGBA:
	case IVideoRenderView::PixFormat::ARGB:
	{
		frame->data[0] = (uint8_t*)data;
	}
		
		break;

	}

	return frame;
}

void MultipleVideosPlayController::Close()
{
	if (!mFilePath.isEmpty()) {
		isRunning = false;
		// 等待线程结束
		if (renderThread && renderThread->joinable()) {
			renderThread->join();
		}
		if (iVideoRenderView) {
			iVideoRenderView->Close();
			iVideoRenderView = NULL;
		}
		binaryFileReader->Close();

		//iVideoRenderView = NULL;
		isRunning = true;
		//renderThread = nullptr;
		//linesize = 0;
		//mWidth = 0;
		//mHeight = 0;
		//fps = 25;//fps默认25帧每秒
		//mPixFormat = IVideoRenderView::PixFormat::RGBA;
		//win_id = NULL;
		//mFilePath = nullptr;
		if (data) {
			delete data;
			data = NULL;
		}
	}

}

void MultipleVideosPlayController::Resize(int width, int height)
{
	if (iVideoRenderView) {
		iVideoRenderView->Scale(width, height);
	}
}

MultipleVideosPlayController::MultipleVideosPlayController()
{
}

MultipleVideosPlayController::~MultipleVideosPlayController()
{
}
